import os
from Utilities.AutoGetOperator.selectionMethod.selectPackage import get_func


root_measure_path = os.path.realpath(os.path.dirname(os.path.dirname(__file__)))  # 度量方法所在目录
measure_measure_path = os.path.join(root_measure_path, 'Measure')  # 距离公式所在目录
distance_path = os.path.join(measure_measure_path, 'distance') # 程序所在目录
file_distance__path = os.path.join(distance_path, 'getD.py')  # 目标文件绝对路径
getD=get_func(file_distance__path,'getD')  # 得分函数的获取

root_score_path = os.path.realpath(os.path.dirname(os.path.dirname(__file__)))  # 度量方法所在目录
measure_score_path = os.path.join(root_score_path, 'ScoreFunction')  # 得分函数所在目录
file_score_path = os.path.join(measure_score_path, 'getS.py')  # 目标文件绝对路径
getS=get_func(file_score_path,'getS')  # 得分函数的获取



class Operator_IVQ_ROFS:
    """
        IVQ_ROFS 区间值广义正交模糊集 类
    """

    def __init__(self, data_list=[], weight_list=[], q=3, x=2, a=2, b=2):
        '''
        function: 初始化类的初始值, 具有默认初始值, 和检查数据列表和权重列表维度匹配的功能
        :param data_list: 区间值广义正交模糊向量
        :param weight_list: 权重向量
        :param q: 参数q
        :param x: 参数x
        :param a: 参数a
        :param b: 参数b

        '''

        if len(data_list):
            self.data_list = data_list  # 初始化数据列表
        else:   # 默认初始为一个 5 个模糊数的列表
            self.data_list = [([0.85, 0.95], [0.1, 0.2]), ([0.8, 0.9], [0.1, 0.2]), ([0.85, 0.95], [0.1, 0.2]), ([0.7, 0.8], [0.2, 0.3]),
        ([0.4, 0.5], [0.5, 0.6])]

        if len(weight_list):
            self.weight_list = weight_list  # 初始化权重列表
        else:   # 默认值设为相等
            self.weight_list = [1/len(self.data_list) for i in range(len(self.data_list))]

        # 如果存在数据和权重列表不匹配的情况, 则做切片处理
        if len(self.data_list) != len(self.weight_list):
            min_len = min(len(self.data_list), len(self.weight_list))
            self.data_list = self.data_list[::min_len]
            self.weight_list = self.weight_list[:min_len]

        self.getdis=getD  # 初始化距离公式函数
        self.getsco=getS  # 初始化得分函数

        self.q = q  # 初始化参数 q
        self.x = x  # 初始化参数 x
        self.a = a  # 初始化参数 a
        self.b = b  # 初始化参数 b



    # set function
    def set_data(self, data, *waste1, **waste2):
        """
            funciton    : 修改 datalist
            data        : 数据集, 单个数据形式:（[x,y]，[x,y]）
            return      : 无返回值
        """
        self.data_list = data  # 初始化数据列表

    def set_q(self, q, *waste1, **waste2):
        """
            funciton    : 修改 q parameter
            q           : 实数
            return      : 无返回值
        """
        self.q = q  # 初始化数据列表

    def set_x(self, x, *waste1, **waste2):
        """
            funciton    : 修改 x parameter
            x           : 实数
            return      : 无返回值
        """
        self.x = x  # 初始化数据列表

    def set_a(self, a, *waste1, **waste2):
        """
            funciton    : 修改 y parameter
            a           : 实数
            return      : 无返回值
        """
        self.a = a  # 初始化数据列表

    def set_b(self, b, *waste1, **waste2):
        """
            funciton    : 修改 z parameter
            b           : 实数
            return      : 无返回值
        """
        self.b = b # 初始化数据列表

    def set_weight(self, weight, *waste1, **waste2):
        """
            funciton    : 修改 weight
            weigh       : 权重想来给你
            return      : 无返回值
        """
        self.weight_list = weight

    # 基础运算法则相关
    def is_include(self, a1, a2, *waste1, **waste2):
        """
            funciton    : 判断包含关系
            a1          : 一个模糊集, 形式:（[x,y]，[x,y]）
            a2          : 一个模糊集, 形式:（[x,y]，[x,y]）
            return      : 布尔值
        """
        u_1_f, u_1_r, v_1_f, v_1_r = *a1[0], *a1[1]
        u_2_f, u_2_r, v_2_f, v_2_r = *a2[0], *a2[1]
        if u_1_f <= u_2_f and u_1_r <= u_2_r and v_1_f >= v_2_f and v_1_r >= v_2_r:
            return True
        return False

    def is_equal(self, a1, a2, *waste1, **waste2):
        """
            funciton    : 判断相等关系
            a1          : 一个模糊集, 形式:（[x,y]，[x,y]）
            a2          : 一个模糊集, 形式:（[x,y]，[x,y]）
            return      : 布尔值
        """
        u_1_f, u_1_r, v_1_f, v_1_r = *a1[0], *a1[1]
        u_2_f, u_2_r, v_2_f, v_2_r = *a2[0], *a2[1]
        if u_1_f == u_2_f and u_1_r == u_2_r and v_1_f == v_2_f and v_1_r == v_2_r:
            return True
        return False

    def is_legal(self, a, q=0, *waste1, **waste2):
        """
            funciton    : 判断模糊集是否符合广义正交的条件
            a           : 一个模糊集, 形式:（[x,y]，[x,y]）
            return      : 布尔值
        """
        if q < 1:
            q = self.q
        u_f, u_r, v_f, v_r = *a[0], *a[1]
        if (u_r ** q + v_r ** q) > 1:
            return False
        return True

    def complement(self, a, *waste1, **waste2):
        """
            function : 区间值广义正交模糊集的 补 运算
            a        : 一个模糊集, 形式:（[x,y]，[x,y]）
            return   : 补集, 形式:（[x,y]，[x,y]）
        """
        u_f, u_r, v_f, v_r = *a[0], *a[1]
        return ([v_f, v_r], [u_f, u_r])

    def intersect(self, a1, a2, *waste1, **waste2):
        """
            funciton    : 区间值广义正交模糊集的 交 运算
            a1          : 一个模糊集, 形式:（[x,y]，[x,y]）
            a2          : 一个模糊集, 形式:（[x,y]，[x,y]）
            return      : 交集, 形式:（[x,y]，[x,y]）
        """
        u_1_f, u_1_r, v_1_f, v_1_r = *a1[0], *a1[1]
        u_2_f, u_2_r, v_2_f, v_2_r = *a2[0], *a2[1]
        return ([min(u_1_f, u_2_f), min(u_1_r, u_2_r)],
                [max(v_1_f, v_2_f), max(v_1_r, v_2_r)])

    def unite(self, a1, a2, *waste1, **waste2):
        """
            funciton    : 区间值广义正交模糊集的 并 运算
            a1          : 一个模糊集, 形式:（[x,y]，[x,y]）
            a2          : 一个模糊集, 形式:（[x,y]，[x,y]）
            return      : 并集, 形式:（[x,y]，[x,y]）
        """
        u_1_f, u_1_r, v_1_f, v_1_r = *a1[0], *a1[1]
        u_2_f, u_2_r, v_2_f, v_2_r = *a2[0], *a2[1]
        return ([max(u_1_f, u_2_f), max(u_1_r, u_2_r)],
                [min(v_1_f, v_2_f), min(v_1_r, v_2_r)])

    def add(self, a1, a2, q=0, *waste1, **waste2):
        """
            funciton    : 区间值广义正交模糊集的 和 运算
            a1          : 一个模糊集, 形式:（[x,y]，[x,y]）
            a2          : 一个模糊集, 形式:（[x,y]，[x,y]）
            return      : 加法结果, 形式:（[x,y]，[x,y]）
        """
        u_1_f, u_1_r, v_1_f, v_1_r = *a1[0], *a1[1]
        u_2_f, u_2_r, v_2_f, v_2_r = *a2[0], *a2[1]
        if q <= 0:
            q = self.q
        u_f = (u_1_f ** q + u_2_f ** q - (u_1_f ** q) * (u_2_f ** q)) ** (1 / q)
        u_r = (u_1_r ** q + u_2_r ** q - (u_1_r ** q) * (u_2_r ** q)) ** (1 / q)
        v_f = (v_1_f) * (v_2_f)
        v_r = (v_1_r) * (v_2_r)
        return ([u_f, u_r], [v_f, v_r])

    def multi(self, a1, a2, q=0, *waste1, **waste2):
        """
            funciton    : 区间值广义正交模糊集的 积 运算
            a1          : 一个模糊集, 形式:（[x,y]，[x,y]）
            a2          : 一个模糊集, 形式:（[x,y]，[x,y]）
            return      : 乘法结果, 形式:（[x,y]，[x,y]）
        """
        u_1_f, u_1_r, v_1_f, v_1_r = *a1[0], *a1[1]
        u_2_f, u_2_r, v_2_f, v_2_r = *a2[0], *a2[1]
        if q <= 0:
            q = self.q
        u_f = (u_1_f) * (u_2_f)
        u_r = (u_1_r) * (u_2_r)
        v_f = (v_1_f ** q + v_2_f ** q - (v_1_f ** q) * (v_2_f ** q)) ** (1 / q)
        v_r = (v_1_r ** q + v_2_r ** q - (v_1_r ** q) * (v_2_r ** q)) ** (1 / q)
        return ([u_f, u_r], [v_f, v_r])

    def kmulti(self, a, k, q=0, *waste1, **waste2):
        """
            function : 区间值广义正交模糊集的 数乘 运算
            a        : 一个模糊集, 形式:（[x,y]，[x,y]）
            k        : ka 的常数 k
            return   : 数乘 运算法则 的值，形式：（[x,y]，[x,y]）
        """
        u_a_f, u_a_r, v_a_f, v_a_r = *a[0], *a[1]
        if q <= 0:
            q = self.q
        u_f = (1 - (1 - (u_a_f) ** q) ** k) ** (1 / q)
        u_r = (1 - (1 - (u_a_r) ** q) ** k) ** (1 / q)
        v_f = (v_a_f) ** k
        v_r = (v_a_r) ** k
        return ([u_f, u_r], [v_f, v_r])

    def pow(self, a, k, q=0, *waste1, **waste2):
        """
            function : 区间值广义正交模糊集的 乘方 运算
            a        : 一个模糊集, 形式:（[x,y]，[x,y]）
            k        : ka 的常数 k
            return   : 乘方 运算法则 的值，形式：（[x,y]，[x,y]）
        """
        u_a_f, u_a_r, v_a_f, v_a_r = *a[0], *a[1]
        if q <= 0:
            q = self.q
        v_f = (1 - (1 - (v_a_f) ** q) ** k) ** (1 / q)
        v_r = (1 - (1 - (v_a_r) ** q) ** k) ** (1 / q)
        u_f = (u_a_f) ** k
        u_r = (u_a_r) ** k
        return ([u_f, u_r], [v_f, v_r])

    def subtract(self, a1 , a2, q=0, *waste1, **waste2):
        '''
        function: 区间值广义正交的减法
        :param a1: 一个模糊集, 形式:（[x,y]，[x,y]）
        :param a2: 一个模糊集, 形式:（[x,y]，[x,y]）
        :param q:
        :return: 一个模糊集, 形式:（[x,y]，[x,y]）
        '''
        if q<=0:
            q=self.q
        u1=a1[0][0] * a2[1][0]
        u2=a1[0][1] * a2[1][1]
        v1=pow(pow(a1[1][0], q) + pow(a2[0][0], q) - pow(a1[1][0], q) * pow(a2[0][0], q), 1/q)
        v2=pow(pow(a1[1][1], q) + pow(a2[0][1], q) - pow(a1[1][1], q) * pow(a2[0][1], q), 1/q)

        return ([u1,u2],[v1,v2])

    def divid(self, a1 , a2, q=0, *waste1, **waste2):
        '''
        function: 区间值广义正交的除法
        :param a1: 一个模糊集, 形式:（[x,y]，[x,y]）
        :param a2: 一个模糊集, 形式:（[x,y]，[x,y]）
        :param q:
        :return: 一个模糊集, 形式:（[x,y]，[x,y]）
        '''
        u1= pow(pow(a1[0][0], q) + pow(a2[1][0], q) - pow(a1[0][0], q) * pow(a2[1][0], q), 1/q)
        u2= pow(pow(a1[0][1], q) + pow(a2[1][1], q) - pow(a1[0][1], q) * pow(a2[1][1], q), 1/q)
        v1= a1[1][0] * a2[0][0]
        v2= a1[1][1] * a2[0][1]

        return ([u1,u2],[v1,v2])

    def sortdata(self):
        """
            function : 根据模糊数得分排列
            a        : 一个模糊集, 形式:（[x,y]，[x,y]）
            return   : PWA 集结后的数据结果，形式：（[x,y]，[x,y]）
        """
        s_list = [[self.getsco(ai,self.q).getScore(), ai] for ai in self.data_list]
        s_list.sort(key=lambda x: x[0], reverse=True)
        return [ai[1] for ai in s_list]



